#include <string.h>
#include<netinet/in.h>  // sockaddr_in
#include<sys/types.h>  // socket
#include<sys/socket.h>  // socket
#include<stdio.h>    // printf
#include<stdlib.h>    // exit

#include <gtk/gtk.h>

#include"filedialog.h"
#include "msgqueuelock.h"
#include "search.h"

#define SERVER_PORT 9116
#define LENGTH_OF_LISTEN_QUEUE 5
#define BUFFER_SIZE 1024

extern int sockfd;
GtkWidget * lb_who;
GtkWidget * lb_filename;

void * thread_send_file(gpointer pkg)
{
    printf("发送线程开始\n");

    struct Package i_pkg;

    int len,result;
    struct sockaddr_in client_addr;

    int client_socket = socket(AF_INET,SOCK_STREAM,0);
    if(client_socket < 0)
    {
        perror("create socket failed\n");
        free(pkg);
        g_thread_exit(NULL);
    }
    bzero(&client_addr,sizeof(client_addr));
    client_addr.sin_family = AF_INET;
    client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    client_addr.sin_port = SERVER_PORT;

    // 绑定客户端的socket和客户端的socket地址结构 非必需
    //    if(-1 == (bind(client_socket, (struct sockaddr*)&client_addr, sizeof(client_addr))))
    len = sizeof(client_addr);
    result = connect(client_socket,(struct sockaddr *)&client_addr,len);
    if(result  < 0){
        perror("Can Not Connect To Server IP:");
        free(pkg);
        close(client_socket);
        g_thread_exit(NULL);
    }

    char buffer[BUFFER_SIZE];
    char * filename = ((struct Package *)pkg)->other;

    //char * filename = pkg;
    printf("该文件名称%s\n",filename);
    FILE *fp = fopen(filename,"r");
    if(NULL == fp)
    {
        printf("File:%s Not Found\n",filename);
    }
    else
    {
        {
            i_pkg.type = 4;
            i_pkg.sock = sockfd;
            i_pkg.destination = ((struct Package *)pkg)->destination;
            char * msg = "传输开始";
            sprintf(i_pkg.msg,"%s",msg);
            printf("socket %d\tid %d\n");
            write(sockfd,&i_pkg,sizeof(struct Package));
        }
        gdk_threads_enter();
        AddMessage(i_pkg.destination,i_pkg.msg);
        gdk_threads_leave();

        bzero(buffer, BUFFER_SIZE);
        int length = 0;
        while((length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)
        {
            if(send(client_socket, buffer, length, 0) < 0)
            {
                printf("Send File:%s Failed./n", filename);
                break;
            }
            bzero(buffer, BUFFER_SIZE);
        }
        // 关闭文件
        fclose(fp);
        printf("File:%s Transfer Successful!\n", filename);
    }

    free(pkg);
    close(client_socket);
    printf("发送线程终止\n");
    {
        i_pkg.type = 4;
        i_pkg.sock = sockfd;
        i_pkg.destination = ((struct Package *)pkg)->destination;
        char * msg = "传输完成";
        sprintf(i_pkg.msg,"%s",msg);
        printf("socket %d\tid %d\n");
        write(sockfd,&i_pkg,sizeof(struct Package));
    }
    gdk_threads_enter();
    AddMessage(i_pkg.destination,i_pkg.msg);
    gdk_threads_leave();

    g_thread_exit(NULL);
}

void * thread_accept_file()
{
    printf("接收线程开始\n");

    struct sockaddr_in server_addr;
    bzero(&server_addr, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htons(INADDR_ANY);
    server_addr.sin_port = SERVER_PORT;

    // 创建socket，若成功，返回socket描述符
    int server_socket_fd = socket(PF_INET, SOCK_STREAM, 0);
    if(server_socket_fd < 0)
    {
        perror("Create Socket Failed:");
    }

    // 绑定socket和socket地址结构
    if(-1 == (bind(server_socket_fd, (struct sockaddr*)&server_addr, sizeof(server_addr))))
    {
        perror("Server Bind Failed:");
        close(server_socket_fd);
        g_thread_exit(NULL);
    }
    printf("listen\n");
    // socket监听
    if(-1 == (listen(server_socket_fd, LENGTH_OF_LISTEN_QUEUE)))
    {
        perror("Server Listen Failed:");
        close(server_socket_fd);
        g_thread_exit(NULL);
    }
    struct sockaddr_in client_addr;
    socklen_t client_addr_length = sizeof(client_addr);

    int socket_fd = accept(server_socket_fd, (struct sockaddr*)&client_addr, &client_addr_length);//到此阻塞

    gdk_threads_enter();
    const char * s = gtk_label_get_text(GTK_LABEL(lb_filename));//A方发送的文件名
    gdk_threads_leave();

    char * file = strrchr(s,'/')+1;
    FILE *fp = fopen(file, "w+");
    if(NULL == fp)
    {
        printf("File:\t%s Can Not Open To Write\n", file);
        close(socket_fd);
        close(server_socket_fd);
        g_thread_exit(NULL);
    }

    char buffer[BUFFER_SIZE];
    bzero(buffer, BUFFER_SIZE);
    int length = 0;
    while((length = recv(socket_fd, buffer, BUFFER_SIZE, 0)) > 0)
    {
        if(fwrite(buffer, sizeof(char), length, fp) < length)
        {
            printf("File:\t%s Write Failed\n", file);
            break;
        }
        bzero(buffer, BUFFER_SIZE);
    }

    fclose(fp);

    close(socket_fd);
    close(server_socket_fd);
    printf("接收线程终止\n");
    g_thread_exit(NULL);
}

void file_ok_event(GtkWidget * widget,GdkEvent *event,gpointer data)
{

    struct Package pkg;
    {
        pkg.type = 11;
        pkg.sock = sockfd;
        pkg.destination = atoi(gtk_label_get_text(GTK_LABEL(lb_who)));//A方的id
        const char * s = gtk_label_get_text(GTK_LABEL(lb_filename));//A方发送的文件名
        sprintf(pkg.other,"%s",s);
        write(sockfd,&pkg,sizeof(pkg));
    }
    gtk_widget_hide_all(file_dialog);
    g_thread_create(thread_accept_file,NULL,FALSE,NULL);

}

void file_refuse_event(GtkWidget * widget,GdkEvent *event,gpointer data)
{
    struct Package pkg;
    {
        pkg.type = 4;
        pkg.sock = sockfd;
        const gchar * id = gtk_label_get_text(GTK_LABEL(lb_who));
        pkg.destination = atoi(id);
        sprintf(pkg.msg,"%s","对方拒绝接受文件！");
        write(sockfd,&pkg,sizeof(pkg));
    }
    gtk_widget_hide_all(file_dialog);
}


void init_file_dialog(int who, const char *filename)
{
    if(file_dialog == NULL){

        GtkWidget * info_vbox;
        GtkWidget * info_hbox;

        GtkWidget * who_hbox;
        GtkWidget * filename_hbox;
        GtkWidget * bt_ok;
        GtkWidget * bt_refuse;

        GtkWidget * const_lb_who;
        GtkWidget * const_lb_filename;
        GtkWidget * filename_show;


        file_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        gtk_window_set_title(GTK_WINDOW(file_dialog),"文件传输请求");
        gtk_window_set_position( GTK_WINDOW(file_dialog),GTK_WIN_POS_CENTER_ALWAYS);
        gtk_widget_set_size_request(GTK_WIDGET(file_dialog),250,150);

        const_lb_who = gtk_label_new("来自：");
        const_lb_filename = gtk_label_new("文件名：");

        char i_who[20];
        sprintf(i_who,"%d",who);
        lb_who = gtk_label_new(i_who);
        lb_filename = gtk_label_new(filename);
        char * s = strrchr(filename,'/');
        filename_show = gtk_label_new(s+1);

        bt_ok = gtk_button_new_with_label("接收");
        bt_refuse = gtk_button_new_with_label("拒绝");

        who_hbox = gtk_hbox_new(FALSE,10);
        filename_hbox = gtk_hbox_new(FALSE,10);
        info_hbox = gtk_hbox_new(FALSE,10);
        info_vbox = gtk_vbox_new(FALSE,10);

        gtk_box_pack_start(GTK_BOX(who_hbox),const_lb_who,FALSE,FALSE,0);
        gtk_box_pack_start(GTK_BOX(who_hbox),lb_who,FALSE,FALSE,0);
        gtk_box_pack_start(GTK_BOX(filename_hbox),const_lb_filename,FALSE,FALSE,0);
        gtk_box_pack_start(GTK_BOX(filename_hbox),filename_show,FALSE,FALSE,0);

        gtk_box_pack_start(GTK_BOX(info_hbox),bt_ok,FALSE,FALSE,50);
        gtk_box_pack_start(GTK_BOX(info_hbox),bt_refuse,FALSE,FALSE,0);

        gtk_box_pack_start(GTK_BOX(info_vbox),who_hbox,FALSE,FALSE,10);
        gtk_box_pack_start(GTK_BOX(info_vbox),filename_hbox,FALSE,FALSE,10);
        gtk_box_pack_start(GTK_BOX(info_vbox),info_hbox,FALSE,FALSE,10);

        gtk_container_add(GTK_CONTAINER(file_dialog),info_vbox);

        g_signal_connect((gpointer)bt_ok,"button_press_event",G_CALLBACK(file_ok_event),NULL);
        g_signal_connect((gpointer)bt_refuse,"button_press_event",G_CALLBACK(file_refuse_event),NULL);
        g_signal_connect((gpointer)file_dialog,"delete_event",G_CALLBACK(file_refuse_event),NULL);
    }
}

